import { useEffect, useRef, useCallback, useState } from 'react'
import { useFilesStore } from '@/store'
import { useThemeStore } from '@/store/modules/useThemeStore'
import { ThemeMode } from '@/enums'
import { useShallow } from 'zustand/react/shallow'
import SimpleMindMap from 'simple-mind-map'
import { Button } from 'antd'

export default function MindMap(): React.JSX.Element {
  const containerRef = useRef<HTMLDivElement | null>(null)
  const mindRef = useRef<any>(null)
  const handlerRef = useRef<(() => void) | null>(null)
  const updatingRef = useRef(false)
  const lastPathRef = useRef<string | null>(null)
  const [formatError, setFormatError] = useState(false)

  const { currentFile, content, setContent } = useFilesStore(
    useShallow((state) => ({
      currentFile: state.curState.currentFile,
      content: state.mindContent,
      setContent: state.setContent
    }))
  )
  const theme = useThemeStore((state) => state.theme)

  const getDefaultData = useCallback(
    (name?: string) => ({ data: { text: name || '中心主题' } }),
    []
  )

  const parse = useCallback(
    (str: string | null | undefined, name?: string) => {
      const empty = !str || str.trim() === '' || str.trim() === '{}'
      if (empty) return { data: getDefaultData(name), ok: true, empty: true }
      try {
        const obj = JSON.parse(str)
        if (obj && typeof obj === 'object' && obj.data && typeof obj.data.text === 'string') {
          return { data: obj, ok: true, empty: false }
        }
        return { data: getDefaultData(name), ok: false, empty: false }
      } catch {
        return { data: getDefaultData(name), ok: false, empty: false }
      }
    },
    [getDefaultData]
  )

  useEffect(() => {
    if (!containerRef.current || mindRef.current) return
    const mindTheme = theme === ThemeMode.DARK ? 'dark' : 'default'
    mindRef.current = new (SimpleMindMap as any)({
      el: containerRef.current,
      theme: mindTheme,
      openPerformance: true
    })
    const handler = () => {
      if (!mindRef.current || updatingRef.current) return
      const data = mindRef.current.getData?.()
      if (!data) return
      setContent(JSON.stringify(data))
    }
    handlerRef.current = handler
    mindRef.current.on?.('data_change', handler)
    return () => {
      if (handlerRef.current && mindRef.current) {
        mindRef.current.off?.('data_change', handlerRef.current)
      }
      mindRef.current?.destroy?.()
      mindRef.current = null
      handlerRef.current = null
      lastPathRef.current = null
    }
  }, [theme, setContent])

  useEffect(() => {
    if (!mindRef.current) return
    try {
      const mindTheme = theme === ThemeMode.DARK ? 'dark' : 'default'
      mindRef.current.setTheme?.(mindTheme)
    } catch {
      void 0
    }
  }, [theme])

  useEffect(() => {
    if (!mindRef.current || !currentFile?.path || updatingRef.current) return
    const switched = lastPathRef.current !== currentFile.path
    const name = currentFile.fileName || '中心主题'
    const { data, ok, empty } = parse(content, name)
    const currStr = JSON.stringify(mindRef.current.getData?.())
    if (!switched && content === currStr) return
    lastPathRef.current = currentFile.path
    if (ok) {
      if (formatError) setFormatError(false)
      if (switched && empty) {
        const str = JSON.stringify(data)
        updatingRef.current = true
        setContent(str)
        mindRef.current.setData?.(data)
        setTimeout(() => {
          updatingRef.current = false
        }, 200)
      } else {
        try {
          updatingRef.current = true
          mindRef.current.setData?.(data)
          setTimeout(() => {
            updatingRef.current = false
          }, 100)
        } catch {
          updatingRef.current = false
          void 0
        }
      }
    } else {
      setFormatError(true)
    }
  }, [currentFile?.path, currentFile?.fileName, content, parse, setContent, formatError])

  const formatFix = useCallback(() => {
    if (!currentFile || !mindRef.current) return
    const name = currentFile.fileName || '中心主题'
    const def = getDefaultData(name)
    const str = JSON.stringify(def)
    updatingRef.current = true
    mindRef.current.setData?.(def)
    setContent(str)
    setFormatError(false)
    setTimeout(() => {
      updatingRef.current = false
    }, 200)
  }, [currentFile, getDefaultData, setContent])

  useEffect(() => {
    if (!currentFile?.path) return
    const stop = window.fsApi?.onFileChanged?.((fp: string) => {
      if (fp !== currentFile.path || !mindRef.current) return
      updatingRef.current = true
      window.fsApi
        ?.readFile(fp)
        .then((txt) => {
          const { data, ok } = parse(txt, currentFile.fileName)
          if (ok) {
            setFormatError(false)
            mindRef.current?.setData?.(data)
            setContent(JSON.stringify(data))
          } else {
            setFormatError(true)
          }
        })
        .finally(() =>
          setTimeout(() => {
            updatingRef.current = false
          }, 200)
        )
    })
    window.fsApi?.watch?.({ filePath: currentFile.path })
    return () => {
      stop && stop()
      window.fsApi?.stopWatch?.()
    }
  }, [currentFile?.path, currentFile?.fileName, parse, setContent])

  useEffect(() => {
    if (!currentFile?.path || updatingRef.current) return
    const timer = setTimeout(() => {
      window.fsApi?.writeFile(currentFile.path, content || '')
    }, 800)
    return () => clearTimeout(timer)
  }, [content, currentFile?.path])
  if (!currentFile) {
    return (
      <div className="w-full h-full inset-0 flex items-center justify-center bg-bg2">
        <div className="text-text3 text-lg">请先打开一个思维导图文件</div>
      </div>
    )
  }

  if (formatError) {
    return (
      <div className="absolute inset-0 flex items-center justify-center bg-black/10">
        <div className="text-center p-6 bg-bg2 rounded-lg shadow-xl">
          <div className="text-text3 text-lg mb-4">当前文件 {currentFile?.fileName} 格式不匹配</div>
          <div className="text-text1 text-sm mb-6">
            点击下方按钮初始化为标准格式（会覆盖原内容）
          </div>
          <Button
            type="primary"
            onClick={formatFix}
            style={{ background: 'var(--primary)', borderWidth: 0 }}
          >
            格式化并初始化
          </Button>
        </div>
      </div>
    )
  }

  return (
    <div className="p-4 h-full w-full overflow-hidden relative">
      <div ref={containerRef} className="w-full h-full rounded " />
    </div>
  )
}
